import React, { useMemo, useState } from 'react'
import useSWR from 'swr'
import { api } from '../lib/api'
import { MartingalePlan, MartingaleStep } from '../types'
import {
  Activity,
  AlertTriangle,
  CheckCircle2,
  Clock,
  Loader2,
  Trash2,
  TrendingUp,
} from 'lucide-react'

interface MartingaleBoxProps {
  traderId: string
}

type PlanStatus = 'arming' | 'running' | 'closing' | 'completed'

interface MartingaleSummary {
  active: number
  closing: number
  completed: number
  deployed: number
  nextStep?: {
    symbol: string
    size: number
    price: number
  }
}

const statusMeta: Record<PlanStatus, { label: string; className: string }> = {
  arming: {
    label: 'ARMING',
    className: 'border-sky-500/40 bg-sky-500/10 text-sky-200',
  },
  running: {
    label: 'RUNNING',
    className: 'border-emerald-500/40 bg-emerald-500/10 text-emerald-200',
  },
  closing: {
    label: 'CLOSING',
    className: 'border-amber-500/40 bg-amber-500/10 text-amber-200',
  },
  completed: {
    label: 'COMPLETED',
    className: 'border-gray-600 bg-gray-800/70 text-gray-300',
  },
}

const statusOrder: Record<PlanStatus, number> = {
  running: 0,
  arming: 1,
  closing: 2,
  completed: 3,
}

const defaultSummary: MartingaleSummary = {
  active: 0,
  closing: 0,
  completed: 0,
  deployed: 0,
}

export const MartingaleBox: React.FC<MartingaleBoxProps> = ({ traderId }) => {
  const {
    data: plans,
    error,
    isLoading,
    mutate,
  } = useSWR<MartingalePlan[]>(
    traderId ? `martingale-${traderId}` : null,
    () => api.getTraderMartingale(traderId),
    { refreshInterval: 3000 }
  )
  const [deletingPlanId, setDeletingPlanId] = useState<string | null>(null)
  const [deleteError, setDeleteError] = useState<string | null>(null)

  const summary = useMemo(() => buildSummary(plans), [plans])
  const sortedPlans = useMemo(() => sortPlans(plans), [plans])

  const handleDelete = async (planId: string) => {
    if (!traderId || deletingPlanId === planId) {
      return
    }
    const confirmed = window.confirm('确定删除该马丁格尔计划？此操作不可恢复')
    if (!confirmed) {
      return
    }
    setDeleteError(null)
    setDeletingPlanId(planId)
    try {
      await api.deleteTraderMartingale(traderId, planId)
      await mutate()
    } catch (err) {
      const message = err instanceof Error ? err.message : '删除失败'
      setDeleteError(message)
    } finally {
      setDeletingPlanId(null)
    }
  }

  if (!traderId) {
    return null
  }

  if (error) {
    return <ErrorState message={error.message} />
  }

  if (isLoading && !plans) {
    return <LoadingState />
  }

  if (!plans || plans.length === 0) {
    return <EmptyState />
  }

  return (
    <div className="space-y-5">
      {deleteError && (
        <div className="rounded-xl border border-red-500/30 bg-red-500/5 px-4 py-2 text-sm text-red-200">
          删除马丁格尔计划失败：{deleteError}
        </div>
      )}
      <SummaryGrid summary={summary} />
      <div className="grid grid-cols-1 gap-6">
        {sortedPlans.map((plan) => (
          <PlanCard
            key={plan.id}
            plan={plan}
            onDelete={handleDelete}
            isDeleting={deletingPlanId === plan.id}
          />
        ))}
      </div>
    </div>
  )
}

const PlanCard: React.FC<{
  plan: MartingalePlan
  onDelete: (planId: string) => void
  isDeleting: boolean
}> = ({ plan, onDelete, isDeleting }) => {
  const status = getPlanStatus(plan)
  const filledSteps = plan.steps.filter((step) => step.filled).length
  const progress = plan.steps.length
    ? Math.round((filledSteps / plan.steps.length) * 100)
    : 0
  const pendingIndex = plan.steps.findIndex((step) => step.pending)
  const nextIndex =
    pendingIndex >= 0
      ? pendingIndex
      : plan.steps.findIndex((step) => !step.filled)
  const nextStep = nextIndex >= 0 ? plan.steps[nextIndex] : undefined

  const accentGradient =
    plan.side === 'long'
      ? 'from-emerald-500/30 via-emerald-500/10'
      : 'from-rose-500/30 via-rose-500/10'

  return (
    <div className="relative overflow-hidden rounded-3xl border border-white/5 bg-[#080d14] shadow-[0_20px_60px_rgba(0,0,0,0.45)]">
      <div
        className={`pointer-events-none absolute inset-x-0 top-0 h-32 bg-gradient-to-b ${accentGradient} to-transparent opacity-70`}
      />

      <div className="relative space-y-6 p-6">
        <div className="flex flex-wrap items-start justify-between gap-4">
          <div>
            <div className="text-[11px] uppercase tracking-[0.3em] text-white/40">
              {plan.id.slice(0, 8)}
            </div>
            <div className="mt-1 flex flex-wrap items-center gap-2 text-2xl font-semibold text-white">
              <span className="font-mono tracking-wide">{plan.symbol}</span>
              <span
                className={`rounded-full px-3 py-1 text-xs font-semibold uppercase ${plan.side === 'long' ? 'bg-emerald-500/20 text-emerald-200' : 'bg-rose-500/20 text-rose-200'}`}
              >
                {plan.side}
              </span>
            </div>
          </div>

          <div className="flex items-center gap-2">
            <StatusBadge status={status} />
            <button
              type="button"
              onClick={() => onDelete(plan.id)}
              disabled={isDeleting}
              className={`group flex items-center gap-2 rounded-full border border-red-500/30 px-3 py-1 text-xs uppercase tracking-wide text-red-200 transition hover:border-red-400 hover:bg-red-500/10 ${isDeleting ? 'opacity-60' : ''}`}
              title="删除该计划"
            >
              {isDeleting ? (
                <Loader2 className="h-4 w-4 animate-spin" />
              ) : (
                <Trash2 className="h-4 w-4" />
              )}
              <span className="hidden font-medium sm:inline">删除</span>
            </button>
          </div>
        </div>

        <div className="grid gap-6 lg:grid-cols-[1.15fr_0.85fr]">
          <PlanMetrics
            plan={plan}
            nextStep={nextStep}
            progress={progress}
            status={status}
          />
          <PlanStepList steps={plan.steps} activeIndex={nextIndex} />
        </div>
      </div>

      <div className="border-t border-white/5 bg-white/[0.02] px-6 py-4">
        <div className="flex flex-wrap items-center gap-3 text-[11px] uppercase tracking-widest text-white/50">
          <span className="rounded-full border border-white/10 px-3 py-1 font-mono">
            {plan.config.max_steps} steps
          </span>
          <span className="rounded-full border border-white/10 px-3 py-1 font-mono">
            {plan.config.multiplier.toFixed(2)}×
          </span>
          <span className="rounded-full border border-white/10 px-3 py-1 font-mono">
            {plan.config.spacing}% gap
          </span>
          <span className="ml-auto rounded-full border border-white/10 px-3 py-1">
            {plan.config.loop ? 'LOOPING' : 'ONE-SHOT'}
          </span>
        </div>
      </div>
    </div>
  )
}

const PlanMetrics: React.FC<{
  plan: MartingalePlan
  nextStep?: MartingaleStep
  progress: number
  status: PlanStatus
}> = ({ plan, nextStep, progress, status }) => {
  const qtyDisplay =
    plan.total_qty > 0
      ? `${plan.side === 'long' ? '+' : '-'}${plan.total_qty.toFixed(4)}`
      : '待触发'
  const notionalDisplay =
    plan.total_notional > 0 ? formatUsd(plan.total_notional, 0) : '-'
  const takeProfitDisplay =
    plan.current_take_profit > 0
      ? plan.current_take_profit.toFixed(4)
      : plan.config.take_profit
        ? `+${plan.config.take_profit}%`
        : '-'
  const stopLossDisplay =
    plan.current_stop_loss > 0
      ? plan.current_stop_loss.toFixed(4)
      : plan.config.stop_loss
        ? `-${plan.config.stop_loss}%`
        : '-'

  return (
    <div className="space-y-5 rounded-2xl border border-white/5 bg-white/[0.02] p-4 backdrop-blur-[2px]">
      <div className="flex items-center justify-between gap-3 text-[11px] uppercase tracking-wide text-white/60">
        <span>执行进度</span>
        <span className="font-mono text-sm text-white">{progress}%</span>
      </div>
      <div className="h-2 rounded-full bg-white/5">
        <div
          className={`h-2 rounded-full ${status === 'completed' ? 'bg-emerald-400' : status === 'closing' ? 'bg-amber-400' : 'bg-sky-400'}`}
          style={{ width: `${progress}%` }}
        />
      </div>

      <div className="grid gap-3 md:grid-cols-2">
        <Metric label="仓位" value={qtyDisplay} hint={notionalDisplay} />
        <Metric label="均价" value={formatNumber(plan.avg_entry, 4)} />
        <Metric label="止盈" value={takeProfitDisplay} tone="positive" />
        <Metric label="止损" value={stopLossDisplay} tone="negative" />
      </div>

      <Metric
        className="bg-transparent"
        label="下一步"
        value={
          nextStep
            ? `${formatUsd(nextStep.size_usd, 0)} @ ${formatNumber(nextStep.trigger_price, 4)}`
            : '全部完成'
        }
        hint={nextStep ? `Step ${nextStep.index + 1}` : '等待新信号'}
      />
    </div>
  )
}

const Metric: React.FC<{
  label: string
  value: React.ReactNode
  hint?: string
  tone?: 'positive' | 'negative'
  className?: string
}> = ({ label, value, hint, tone, className }) => {
  const toneClass =
    tone === 'positive'
      ? 'text-emerald-300'
      : tone === 'negative'
        ? 'text-rose-300'
        : 'text-[#EAECEF]'
  return (
    <div
      className={`rounded-xl border border-white/5 bg-white/[0.01] p-3 text-white ${className ?? ''}`}
    >
      <div className="text-[10px] uppercase tracking-wide text-white/50">
        {label}
      </div>
      <div className={`text-sm font-semibold ${toneClass}`}>{value}</div>
      {hint && <div className="text-[10px] text-white/40">{hint}</div>}
    </div>
  )
}

const PlanStepList: React.FC<{
  steps: MartingaleStep[]
  activeIndex: number
}> = ({ steps, activeIndex }) => {
  const filled = steps.filter((step) => step.filled).length
  return (
    <div className="rounded-2xl border border-white/5 bg-white/[0.01]">
      <div className="flex items-center justify-between border-b border-white/5 px-4 py-3 text-[11px] uppercase tracking-wide text-white/50">
        <span>执行梯度</span>
        <span>
          {filled}/{steps.length} filled
        </span>
      </div>
      <div className="divide-y divide-white/5">
        {steps.map((step, idx) => (
          <PlanStepRow
            key={`${step.index}-${step.order_id ?? idx}`}
            step={step}
            state={resolveStepState(step, idx, activeIndex)}
          />
        ))}
      </div>
    </div>
  )
}

type StepVisualState = 'filled' | 'pending' | 'next' | 'queued'

const stepVisualMeta: Record<
  StepVisualState,
  {
    label: string
    text: string
    pill: string
    icon?: React.ReactNode
  }
> = {
  filled: {
    label: 'FILLED',
    text: 'text-emerald-200',
    pill: 'border-emerald-400/40 bg-emerald-400/10 text-emerald-200',
    icon: <CheckCircle2 className="h-4 w-4 text-emerald-300" />,
  },
  pending: {
    label: 'PENDING',
    text: 'text-amber-200',
    pill: 'border-amber-400/40 bg-amber-400/10 text-amber-200',
    icon: <Clock className="h-4 w-4 text-amber-300" />,
  },
  next: {
    label: 'NEXT',
    text: 'text-sky-200',
    pill: 'border-sky-400/40 bg-sky-400/10 text-sky-200',
    icon: <Activity className="h-4 w-4 text-sky-300" />,
  },
  queued: {
    label: 'QUEUED',
    text: 'text-white/40',
    pill: 'border-white/10 bg-white/5 text-white/60',
  },
}

const PlanStepRow: React.FC<{
  step: MartingaleStep
  state: StepVisualState
}> = ({ step, state }) => {
  const meta = stepVisualMeta[state]
  return (
    <div className="flex items-center justify-between px-4 py-3 text-sm">
      <div className="flex items-center gap-3">
        <span
          className={`flex h-7 w-7 items-center justify-center rounded-full border text-xs font-bold ${meta.pill}`}
        >
          {step.index + 1}
        </span>
        <div>
          <div className="font-mono text-white">
            {formatUsd(step.size_usd, 0)}
          </div>
          <div className="text-[10px] text-white/50">
            @ {formatNumber(step.trigger_price, 4)}
          </div>
        </div>
      </div>
      <div
        className={`flex items-center gap-2 text-[10px] uppercase tracking-wide ${meta.text}`}
      >
        {meta.label}
        {meta.icon}
      </div>
    </div>
  )
}

const StatusBadge: React.FC<{ status: PlanStatus }> = ({ status }) => {
  const meta = statusMeta[status]
  return (
    <span
      className={`rounded-full border px-3 py-1 text-[10px] font-semibold uppercase tracking-widest ${meta.className}`}
    >
      {meta.label}
    </span>
  )
}

const SummaryGrid: React.FC<{ summary: MartingaleSummary }> = ({ summary }) => {
  const cards = [
    {
      label: 'Active Plans',
      value: summary.active,
      sub: '运行 + 待触发',
      icon: <Activity className="h-4 w-4 text-sky-300" />,
    },
    {
      label: 'Closing',
      value: summary.closing,
      sub: '等待平仓',
      icon: <AlertTriangle className="h-4 w-4 text-amber-300" />,
    },
    {
      label: 'Completed',
      value: summary.completed,
      sub: '已完成循环',
      icon: <CheckCircle2 className="h-4 w-4 text-emerald-300" />,
    },
    {
      label: 'Capital Deployed',
      value: summary.deployed > 0 ? formatUsd(summary.deployed, 0) : '-',
      sub: summary.nextStep
        ? `Next ${summary.nextStep.symbol}: ${formatUsd(summary.nextStep.size, 0)} @ ${formatNumber(summary.nextStep.price, 4)}`
        : '等待下一次挂单',
      icon: <TrendingUp className="h-4 w-4 text-[#F0B90B]" />,
    },
  ]

  return (
    <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
      {cards.map((card) => (
        <div
          key={card.label}
          className="rounded-2xl border border-[#1E2329] bg-[#0C1015] p-4"
        >
          <div className="flex items-center justify-between text-[10px] uppercase tracking-wide text-[#6F767E]">
            <span>{card.label}</span>
            {card.icon}
          </div>
          <div className="mt-2 text-2xl font-bold text-[#EAECEF]">
            {card.value}
          </div>
          {card.sub && (
            <div className="text-[11px] text-[#848E9C]">{card.sub}</div>
          )}
        </div>
      ))}
    </div>
  )
}

const LoadingState: React.FC = () => (
  <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
    {[0, 1, 2].map((idx) => (
      <div
        key={idx}
        className="h-48 animate-pulse rounded-2xl border border-[#1E2329] bg-[#0C1015]"
      />
    ))}
  </div>
)

const EmptyState: React.FC = () => (
  <div className="rounded-2xl border border-dashed border-[#2B3139] bg-[#0A0F14] p-8 text-center text-sm text-[#848E9C]">
    <div className="mb-2 text-base font-semibold text-[#EAECEF]">
      暂无马丁格尔计划
    </div>
    <p>当策略触发后会自动展示执行梯度。</p>
  </div>
)

const ErrorState: React.FC<{ message: string }> = ({ message }) => (
  <div className="rounded-2xl border border-red-500/30 bg-red-500/5 p-4 text-sm text-red-200">
    无法加载马丁格尔策略：{message}
  </div>
)

function buildSummary(plans?: MartingalePlan[]): MartingaleSummary {
  if (!plans || plans.length === 0) {
    return { ...defaultSummary }
  }

  return plans.reduce<MartingaleSummary>(
    (acc, plan) => {
      const status = getPlanStatus(plan)
      if (status === 'running' || status === 'arming') {
        acc.active += 1
      }
      if (status === 'closing') {
        acc.closing += 1
      }
      if (status === 'completed') {
        acc.completed += 1
      }
      acc.deployed += plan.total_notional || 0

      const nextIdx = plan.steps.findIndex(
        (step) => !step.filled && !step.pending
      )
      if (!acc.nextStep && nextIdx >= 0) {
        const step = plan.steps[nextIdx]
        acc.nextStep = {
          symbol: plan.symbol,
          size: step.size_usd,
          price: step.trigger_price,
        }
      }

      return acc
    },
    { ...defaultSummary }
  )
}

function sortPlans(plans?: MartingalePlan[]): MartingalePlan[] {
  if (!plans) {
    return []
  }
  return [...plans].sort((a, b) => {
    const statusDiff =
      statusOrder[getPlanStatus(a)] - statusOrder[getPlanStatus(b)]
    if (statusDiff !== 0) {
      return statusDiff
    }
    const timeDiff =
      new Date(b.created_at).getTime() - new Date(a.created_at).getTime()
    if (timeDiff !== 0) {
      return timeDiff
    }
    return a.symbol.localeCompare(b.symbol)
  })
}

function getPlanStatus(plan: MartingalePlan): PlanStatus {
  if (plan.completed) {
    return 'completed'
  }
  if (plan.closing) {
    return 'closing'
  }
  if (plan.total_qty > 0 || plan.steps.some((step) => step.filled)) {
    return 'running'
  }
  return 'arming'
}

function resolveStepState(
  step: MartingaleStep,
  idx: number,
  activeIndex: number
): StepVisualState {
  if (step.filled) {
    return 'filled'
  }
  if (step.pending) {
    return 'pending'
  }
  if (idx === activeIndex) {
    return 'next'
  }
  return 'queued'
}

function formatUsd(value?: number, digits = 0): string {
  if (value === null || value === undefined || Number.isNaN(value)) {
    return '-'
  }
  return `$${value.toLocaleString('en-US', {
    minimumFractionDigits: digits,
    maximumFractionDigits: digits,
  })}`
}

function formatNumber(value?: number, digits = 2): string {
  if (value === null || value === undefined || Number.isNaN(value)) {
    return '-'
  }
  return Number(value).toFixed(digits)
}
